///////////////////////////////////////////////////////////////
//jKeyCrypt  - Command line/ GUI key based text encryption
//  (c) 2012 - BOBdotEXE bobdotexe@gmail.com
//   http://code.google.com/p/jkeycrypt
//
//  For non-commercial use only check website for more info
////////////////////////////////////////////////////////////////
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.NoSuchElementException;
import java.util.Random;
import java.util.Scanner;

import javax.swing.JOptionPane;

/**
 * 
 */

/**
 * @author david
 *
 */
public class jKeyCrypt {
	private static String key="";
	static int x=0;
    static boolean gui=true;
	/**
	 * @param args
	 */
	public static void main(String[] args)  {// jKeyCrypt.jar -e 'Passphrase' 'text to encode'
	
//db		System.out.println(args[0]+" "+args.length);
		String in="";
		String resp=""; //responce string (used within the nogui mode
		String text="";
		String pass="";
		GUI face;//if the GUI is activate it will be stored here
		PrintWriter writeKey=null; //will hold key we're writing to
		PrintWriter mkKey=null;//the Writer for the key file
		Scanner newText=null;//will hold text to be written to key file
		Scanner cmd = new Scanner(System.in);//read user input
        System.out.println("jKeyCrypt v1.3");
        System.out.println("by BOBdotEXE   \n\nhttps://code.google.com/p/jkeycrypt/\n\n");
        String tmp;
		jRead mcp =new jRead();
	   //check the arguments
		if (!(args.length==0)) //if arguments exist
		{
		if (args[0].equals("-nogui")) //if -nogui is passed, 
			{System.out.println("Command line mode");
				gui=false;  //disable the Gui
			}
		if (!(args.length==3)&&!(args[0].equals("-nogui"))&&!(args.length==2)){//if we don't have 3, or two args, and the first ones, not '-gui
			System.out.println("In correct arguments:\n it should be jKeyCrypt.jar (encrypy '-e' /decrypty '-d') passphrase  Text\n example: jKeyCrypt.jar -e password "+'"'+"hello world"+'"');
			System.exit(0);} //they typed something wrong, just give up :)
				
		if (args.length==3)// 3 args needed to process a one-line read.
			{
			if (args[0].equals("-e")){
			 	System.out.println("\nEncoded as <"+mcp.encrypt(args[2],args[1])+">\nthe begining '<' and ending '>' are not part of the code, But copy everyting that's inside.\n\n");
			 	System.exit(0); //close the program
				}
			if (args[0].equals("-d")){
			 	System.out.println("\nDecoded as <"+mcp.decrypt(args[3],args[2])+"\n");
			 	System.exit(0); //close the program
				}
			}
			//for one line without passphrase
			
				
		if (args.length==2)// 4 args needed to process a one-line read.
			{
			if (args[0].equals("-e")){
				System.out.println("\nEncoded as <"+mcp.encrypt(args[1],"")+">\nthe begining '<' and ending '>' are not part of the code, But copy everyting that's inside.\n\n");
				System.exit(0); //close the program
				}
			if (args[0].equals("-d")){
			 	System.out.println("\nDecoded text: <"+mcp.decrypt(args[1],"")+"\n");
			 	System.exit(0); //close the program
				}
			}			
		}//end of arg check
		
		//done handeling Args
		File readKey = new File("key");//open key file
		Scanner keyText = null;    //get scanner to read the key file
		try {//we will try to read the key file.
			keyText = new Scanner(readKey);
			key = keyText.nextLine();
			keyText.close();
			mcp.changeKey(key);
			key=null;
			
			} 
		catch (FileNotFoundException e) 
			{
			if(gui==true) //check key file, GUI eddition
				{	 
				int reply =JOptionPane.showConfirmDialog(null, "Generate one?","No key File Found!", JOptionPane.YES_NO_OPTION);
				
				if (reply==1)
					{
					JOptionPane.showMessageDialog(null,  "Key File Required!","Error!", JOptionPane.ERROR_MESSAGE);
					System.exit(0); 
				    }
				
				//else:
				try {
					mkKey = new PrintWriter("key"); //open the key file
					String sKeyLen = JOptionPane.showInputDialog("Key File Length:  (250+ suggested) :");
					int keyLen = Integer.valueOf(sKeyLen);
					if (keyLen<1)//to small.
							keyLen=20;	
					mkKey.println(mcp.mkKey(keyLen));//Generate a key file that is 'keyLen' characters long, and save the key to a file 
					mkKey.close(); 
					}
				catch (FileNotFoundException e1) 
					{
					JOptionPane.showMessageDialog(null,  "Key File Required!","Could not write file!", JOptionPane.ERROR_MESSAGE);
					System.exit(0); 
					e1.printStackTrace();
					}
				
				 
			}//end of gui version file check
			
			if (gui==false)//check for key File noGUI version
				{
				System.out.println("\nNo key File Found!, Generate one?\n\n(y)es  or (n)o");
				in="";
				in=cmd.nextLine();//get responce
				
				if (!(in.equalsIgnoreCase("y"))) //if anything but 'Y' is typed
					{
					System.out.println("We cannot continue without a key file.\nProgram terminated!");
					System.exit(0);
					}
				//else:
				try 
					{
					mkKey = new PrintWriter("key"); //open the key file
					System.out.println("\nKey File Length:  (250+ suggested):");
					in="";
					in=cmd.nextLine();//get responce
					int keyLen = Integer.valueOf(in);
					if (keyLen<1)//to small.
						keyLen=20;	
					mkKey.println(mcp.mkKey(keyLen));//Generate a key file that is 'keyLen' characters long, and save the key to a file 
					mkKey.close(); 
					}
				catch (FileNotFoundException e1) 
					{
					System.err.println("Could not write file!");
					System.exit(0); 
					e1.printStackTrace();
					}
				
				}//end of GUI-less file not found handler
				
				
				
		}//----------end of File not found execption
	
	catch (NoSuchElementException e1)//if it's blank
		{
		if (gui==true)//gui method for dealing with  blank files
			{
			JOptionPane.showMessageDialog(null,  "Key File Blank!","Can't read file!", JOptionPane.ERROR_MESSAGE);
			key=mcp.mkKey(250);
			try {
				writeKey = new PrintWriter("key");
				} catch (FileNotFoundException e2)
				{
				// TODO Auto-generated catch block
					e2.printStackTrace();
				}//open the key file
			writeKey.println(key);//and save our current 'key' to it
			writeKey.close();
				
			JOptionPane.showMessageDialog(null,  "I filled it in for you.","Temporary File created", JOptionPane.INFORMATION_MESSAGE);
			}
		if (gui==false)//if gui's not on, do the same thing, but with printline
		{
			System.out.println("Keyfile Blank!");
			key=mcp.mkKey(20);
			mkKey.println(key);//Generate a key file that is 250 characters long, and save the key to a file 
			try {
				writeKey = new PrintWriter("key");
				} catch (FileNotFoundException e2) {
				// TODO Auto-generated catch block
			e2.printStackTrace();
			}//open the key file
			writeKey.println(key);//and save our current 'key' to it
			writeKey.close();
			e1.printStackTrace();	
			System.out.println("I filled it in for you.\nTemporary File created");
			}
		}//end of blank file handler
		
	if (gui==true)
	{
		face=new GUI();//start up the GUI
		face.draw();
		
	}
	else
	{
		//----------------------------------------------------------------------------------------------
		//  command line interface bellow
		//------------------------------------------------------------------------------------------------
		System.out.println("Do you want to (e)ncrypt text or (d)ecrypt text? or (m)ore options?\nType e or d or m, then press enter");
		while ((!(in.equalsIgnoreCase("q"))))
			{
			in=cmd.nextLine();
			if (in.equalsIgnoreCase("m"))//show more options
				{
				System.out.println("type: i  to import a key file!");
				System.out.println("type: x  to export your key file!");
				System.out.println("type: g  to generate a new key file!");
				}
			if (in.equalsIgnoreCase("i"))//import a key file -------needs it's own section----------
			{
				System.out.println("\n Please type the path to the file you wish to import:");
				resp=cmd.nextLine();//set the responce to the input
				try
					{
					readKey = new File(resp);
					keyText = new Scanner(readKey);
					key=keyText.nextLine();
					mcp.changeKey(key);
					System.out.println("new key imported, Would you like to overwrite\n your old key file? or just use the key for this session only?");
					resp="";
					while (!(resp.equalsIgnoreCase("o"))&&(!resp.equalsIgnoreCase("s"))) //loop untill they answer 'o' or 's'
						{
						System.out.println("\n (o)verwrite? or (s)ingle session");
						resp=cmd.nextLine();
						}
					if (resp.equalsIgnoreCase("o"))//if they decide to overwrite
							{
							writeKey = new PrintWriter("key");//open the key file
							writeKey.println(key);//and save our current 'key' to it
							writeKey.close();
							System.out.println("Overwrote local key file.");
							}
					}
				catch (FileNotFoundException e2) 
					{
					System.err.println("Could not open file:\n"+resp);
					e2.printStackTrace();
					System.err.println("\n Key not imported, will proccede with old key");
					System.out.println("\n(e)ncrypt text or (d)ecrypt text or (m)ore (q)uit");
					}
				
				
				
			}
			
			if (in.equalsIgnoreCase("e")) 
				{				
				System.out.println("Passphrase:");
				pass=cmd.nextLine();
				
				System.out.println("\n\ntype your text below, it's multi line so pressing [enter] will\n give you a new line, when your done typing,\npress [enter] and on the new line type: &done   then press [enter");
				text="";
				tmp="";
				while (!tmp.equalsIgnoreCase("&done"))//loop untill they type &done
					{
					tmp=cmd.nextLine();
						if (!tmp.equalsIgnoreCase("&done"))
							text=text+"\n"+tmp;
					}
				//text=text.substring(0,text.length()-6);//trim off the extra stuff (\n &done/n)

				System.out.println("\nEncoded as <"+mcp.encrypt(text,pass)+">\nthe begining '<' and ending '>' are not part of the code,\nYou can leave them in,and it will still work (as long as you copied both)\n");
				
			
			in="";
			}
			if (in.equalsIgnoreCase("q"))
				System.exit(0);
			
			
			if (in.equalsIgnoreCase("d")) 
				{
				System.out.println("\n\nText:");
				text=cmd.nextLine();
				System.out.println("Passphrase:");
				pass=cmd.nextLine();
				System.out.println("Decoded as :"+mcp.decrypt(text,pass)+"\n\n");
			
				in="";
				}
			System.out.println("\n(e)ncrypt text or (d)ecrypt text or (m)ore or (q)uit");
			}
		}
	}



	
	
	
}
